package com.isunimp.sample.springboot.web.aop.aop;

import com.isunimp.sample.springboot.web.aop.service.impl.ServiceImpl;
import org.apache.catalina.connector.RequestFacade;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * @ClassName: TestAop
 * @Description: TODO
 * @Author: isunimp
 * @Date: 2018/8/7
 */
@Aspect
@Component
public class TestAop {

    @Pointcut("within(com.isunimp.sample.springboot.web.aop.service.impl.ServiceImpl)")
    public void within1() {

    }

    @Pointcut("execution(public * com.isunimp.sample.springboot.web.aop.controller.*Controller.*(..))")
    public void controllerPointcut(){

    }

    @Pointcut("@annotation(org.springframework.web.bind.annotation.PostMapping)")
    public void myPointcut(){

    }

    @Before(value = "within1()")
    public void before(JoinPoint joinPoint) {
        ServiceImpl service = (ServiceImpl)joinPoint.getThis();
         System.out.println("before:" + joinPoint.getThis());
    }

    @Before(value = "myPointcut() && args(id,..)")
    public void before(JoinPoint joinPoint, String id) {
        System.out.println("before:" + id);
    }

    @AfterReturning(value = "controllerPointcut()", returning = "returnVal")
    public Object afterReturning(Object returnVal) {
        System.out.println("afterReturning:" + returnVal);
        returnVal = "hello aop";
        return "hello aop";
    }

    @Around(value = "myPointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        for (int idx = 0; idx < args.length; ++idx) {
            System.out.println("args " + String.valueOf(idx) + ":" + args[idx].getClass().getSimpleName() + ":" + args[idx]);
            RequestFacade requestFacade;
        }
        HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
        InputStream inputStream = request.getInputStream();
        byte[] buffer = new byte[64*1024];
        int length = inputStream.read(buffer);
        String encode = request.getCharacterEncoding();
        byte[] data;
        try {
            data = new byte[length];
            System.arraycopy(buffer, 0, data, 0, length);
        }catch (Exception e){
            return null;
        }
        String str = new String(data, encode);



        System.out.println("around");
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        Annotation[] annotation = method.getAnnotations();
        joinPoint.proceed(new Object[]{"2"});
        return "hello";
    }
}
